﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;

namespace WebCrawling.Data.Extracting
{
    public class HttpRequestSyn
    {
        private String userAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)";
        CookieContainer cookie = null;
        private static HttpRequestSyn request;

        public static HttpRequestSyn Instance
        {
            get
            {
                if (request == null)
                {
                    request = new HttpRequestSyn();

                }
                return request;
            }
        }

        #region IRequestSource

        protected HttpWebRequest GetRequest(Uri uri, string charset = "UTF-8")
        {
            Uri baseURL = new Uri("http://" + uri.Host);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            request.Timeout = 15000;
            //request.KeepAlive = true;
            request.AllowAutoRedirect = true;
            request.MaximumAutomaticRedirections = 50;
            request.ProtocolVersion = HttpVersion.Version11;
            request.Accept = "text/html";
            request.UserAgent = userAgent;
            //request.ContentType = "text/html";
            cookie = new CookieContainer();
            cookie.MaxCookieSize = 1024;
            request.CookieContainer = cookie;
            return request;
        }

        public PageClass GetPage(Uri uri, string charset = "UTF-8")
        {
            if (uri == null)
                return null;

            if (string.IsNullOrEmpty(uri.ToString().Trim()))
                return null;

            Uri baseURL = new Uri("http://" + uri.Host);

            HttpWebRequest request = null;
            HttpWebResponse response = null;
            Stream stream = null;
            StringBuilder sb = new StringBuilder();
            PageClass newpageclass = new PageClass();
            newpageclass.URL = uri;
            try
            {
                request = GetRequest(uri);
                response = (HttpWebResponse)request.GetResponse();
                stream = response.GetResponseStream();
                if (request.RequestUri.ToString() != response.ResponseUri.ToString())
                {
                    baseURL = new Uri("http://" + response.ResponseUri.Host);
                    newpageclass.URL = response.ResponseUri;
                }
                int count;
                byte[] buf = new byte[10240];

                response.Cookies = cookie.GetCookies(baseURL);
                newpageclass.URL = response.ResponseUri;

                if (stream == null)
                    return null;

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    return null;
                }

                if (!response.ContentType.ToLower().StartsWith("text/"))
                {
                    return null;
                }

                do
                {
                    count = stream.Read(buf, 0, buf.Length);

                    if (count != 0)
                    {
                        sb.Append(Encoding.GetEncoding(charset).GetString(buf, 0, count));
                    }
                }
                while (count > 0);
            }
            catch (WebException ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (stream != null) stream.Close();
                if (response != null) response.Close();
                request.Abort();
            }
            newpageclass.html = sb.ToString();
            return newpageclass;
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
        }

        #endregion
    }
    public class PageClass
    {
        public string html;
        public Uri URL;
    }
}
